﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using AutoMapper;
using Jinjia.Approve.Common.Enum;
using Jinjia.Approve.Entity.Entity.JJFlow;
using Jinjia.Approve.IRepository;
using Jinjia.Approve.IRepository.JJFlow;
using Jinjia.Approve.IService.JJFlow;
using Jinjia.Approve.Model.VM.JJFlow;
using JinJia.Core.Base.Exceptions;

namespace Jinjia.Approve.Service.JJFlow
{
    public class JJFlowTrackService : IJJFlowTrackService
    {
        private readonly IFlowTrackRepository _flowTrackRepository;
        private readonly IJJFlowCommentRepository _jjFlowCommentRepository;
        private readonly IFlowInstanceRepository _flowInstanceRepository;
        private readonly IFlowInstanceEmpRepository _flowInstanceEmpRepository;
        private readonly IFlowNodeReferenceRepository _flowNodeReferenceRepository;
        private readonly IFlowNodeRepository _flowNodeRepository;
        private readonly IMapper _mapper;

        public JJFlowTrackService(IFlowTrackRepository flowTrackRepository,
            IJJFlowCommentRepository jjFlowCommentRepository,
            IFlowInstanceRepository flowInstanceRepository,
            IFlowInstanceEmpRepository flowInstanceEmpRepository,
            IFlowNodeReferenceRepository flowNodeReferenceRepository,
            IFlowNodeRepository flowNodeRepository,
            IMapper mapper)
        {
            _flowTrackRepository = flowTrackRepository;
            _jjFlowCommentRepository = jjFlowCommentRepository;
            _flowInstanceRepository = flowInstanceRepository;
            _flowInstanceEmpRepository = flowInstanceEmpRepository;
            _flowNodeReferenceRepository = flowNodeReferenceRepository;
            _flowNodeRepository = flowNodeRepository;
            _mapper = mapper;
        }


        public async Task<int> Save(JjFlowTrackVM data)
        {
            var jjFlowTrack = _mapper.Map<jj_flow_track>(data);
            var id = await _flowTrackRepository.Save(jjFlowTrack);
            return id;
        }

        public async Task Save(List<JjFlowTrackVM> data)
        {
            var list = _mapper.Map<List<jj_flow_track>>(data);
            await _flowTrackRepository.Save(list);
        }

        public async Task RecordTrackInfo(Node next_node, int instance_id, int operate_user_id, int op_type, int user_id, string remark = "", int is_auto = 0)
        {
            var jjFlowCommentVm = _mapper.Map<JjFlowTrackVM>(next_node);
            jjFlowCommentVm.id = 0;
            jjFlowCommentVm.create_user_id = operate_user_id;
            jjFlowCommentVm.instance_id = instance_id;
            jjFlowCommentVm.operation_result = next_node.node_type;
            jjFlowCommentVm.node_id = next_node.id;
            jjFlowCommentVm.node_name = next_node.node_name;
            jjFlowCommentVm.create_time = DateTime.Now;
            jjFlowCommentVm.operation_result = op_type;
            jjFlowCommentVm.action_type = op_type;
            jjFlowCommentVm.action_type_name = op_type == 0 ? "审核通过" : "审核拒绝";
            jjFlowCommentVm.from_emp = user_id.ToString();
            jjFlowCommentVm.remark = remark;
            jjFlowCommentVm.update_user_id = operate_user_id;
            jjFlowCommentVm.update_time = DateTime.Now;

            //结束节点不需要记录到评论表
            var jjFlowTrack = _mapper.Map<jj_flow_track>(jjFlowCommentVm);
            await _flowTrackRepository.Save(jjFlowTrack);

            //写入审批评论数据
            if (jjFlowTrack.operation_result != (int)EnumDb.JJFlowNodeTypeEnum.EndNode)
            {
                var instance = await _flowInstanceRepository.GetById(instance_id);
                if (instance != null)
                {
                    var now = DateTime.Now;
                    //保存评论
                    await _jjFlowCommentRepository.Save(new jj_flow_comment_tbl()
                    {
                        comment = jjFlowTrack.remark,
                        node_name = jjFlowTrack.node_name,
                        node_action = jjFlowTrack.action_type_name,
                        is_append = 0,
                        biz_order_id = instance.biz_order_id,
                        modular_key = instance.modular_key,
                        create_time = now,
                        update_time = now,
                        update_user_id = jjFlowTrack.update_user_id,
                        create_user_id = jjFlowTrack.create_user_id
                    });

                    //轮询更新之前评论的状态
                    await _jjFlowCommentRepository.UpdateIsAppend(instance.biz_order_id, instance.modular_key);
                }
            }
        }

        public async Task<bool> GetApproveTrackModelByInstanceId(int instance_id)
        {
            return await _flowTrackRepository.GetApproveTrackModelByInstanceId(instance_id);
            //var jjFlowTrack = await _flowTrackRepository.GetApproveTrackModelByInstanceId(instance_id);
            //var jjFlowTrackVm = _mapper.Map<JjFlowTrackVM>(jjFlowTrack);
            //return jjFlowTrackVm;
        }

        public async Task<List<JjFlowTrackVM>> GetFlowTrackHistory(string biz_order_id, string modular_key, int flow_instance_id)
        {
            var jjFlowTrack = await _flowTrackRepository.GetListByBizOrderID(biz_order_id, modular_key, flow_instance_id);
            return jjFlowTrack;
        }

        public async Task<List<JjFlowTrackVM>> GetFlowTrackById(int flow_instance_id)
        {
            var jjFlowInstance = await _flowInstanceRepository.GetById(flow_instance_id);
            if (jjFlowInstance == null)
            {
                throw new BusinessException("未找到业务申请信息！");
            }

            //获取节点所有审批人
            var instance_user = await _flowInstanceEmpRepository.GetInstanceUserInfo(flow_instance_id, jjFlowInstance.template_id);
            //获取历史track记录
            var flowTracks = await _flowTrackRepository.GetFlowTracks(flow_instance_id);
            var track_info = _mapper.Map<List<JjFlowTrackVM>>(flowTracks);
            //获取预定轨迹信息
            var referent_nodes = await _flowNodeReferenceRepository.GetReferences(flow_instance_id);

            foreach (var item in track_info)
            {
                item.node_status_type = 0;
                item.emp_list = instance_user.Where(a => a.node_id == item.node_id && a.user_id == item.create_user_id).ToList();
                item.sequence = referent_nodes.First(a => a.node_id == item.node_id).sequence;
            }

            //获取node plan  (未进行的节点信息)
            var plan_nodes = await _flowNodeRepository.GetNodesPlan(flow_instance_id);
            //通过的当前节点信息
            var current_node = await _flowNodeRepository.GetById(jjFlowInstance.current_node_id);

            var new_plan_nodes = plan_nodes.Where(x => x.node_step >= current_node.node_step).ToList();

            //将未来的加入到轨迹中
            foreach (var node in new_plan_nodes)
            {
                var checkNodeIsComplete = await _flowNodeRepository.CheckNodeIsComplete(jjFlowInstance.id, jjFlowInstance.template_id, node.id);
                if (node.id != jjFlowInstance.current_node_id || (node.emp_type == 1 && !checkNodeIsComplete))
                {
                    var jjFlowTrackVm = _mapper.Map<jj_node, JjFlowTrackVM>(node, opts =>
                    {
                        opts.AfterMap((src, des) =>
                        {
                            des.node_status_type = 2;
                            des.node_id = node.id;
                            des.emp_name = node.node_type == (int)EnumDb.JJFlowNodeTypeEnum.EndNode ? "完成" : des.emp_name;
                            des.remark = "";
                            des.emp_list = instance_user.Where(a => a.node_id == node.id && a.is_complete == 0).ToList();
                            des.sequence = referent_nodes.First(a => a.node_id == node.id).sequence; ;
                        });
                    });

                    track_info.Add(jjFlowTrackVm);
                }
            }

            return track_info;
        }

        public async Task<List<JjFlowTrackVM>> GetListByInstanceId(int instance_id)
        {
            var jjFlowTracks = await _flowTrackRepository.GetListByInstanceId(instance_id);
            var jjFlowTrackVms = _mapper.Map<List<JjFlowTrackVM>>(jjFlowTracks);
            return jjFlowTrackVms;
        }

        public async Task<List<JjFlowTrackVM>> GetListAsync(Expression<Func<jj_flow_track, bool>> predicate)
        {
            var flowTracks = await _flowTrackRepository.GetListAsync(predicate);
            return _mapper.Map<List<JjFlowTrackVM>>(flowTracks);
        }
    }
}